using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Domain;
using BusinessTier.Facade.Implementation;
using BusinessTier.Facade.Interface;
using WebMVC.Helpers;
using WebMVC.Models;
using WebMVC.Utils;
using Domain.Type;
using System.Globalization;

namespace WebMVC.Controllers
{
    public class ProductController : ProductControllerBase
    {
        
        private static readonly int ITEMS_COUNT = 4;

        private IProductService productService;
        //private IBillingService billingService;
        private IStaticDataService staticDataService;

        public ProductController() : this(new ProductService()/*, new BillingService()*/, new StaticDataService())
        {
            
        }

        public ProductController(IProductService productService/*, IBillingService billingService*/, IStaticDataService staticDataService)
        {
            this.productService = productService;
            //this.billingService = billingService;
            this.staticDataService = staticDataService;
        }

        //[OutputCache(Duration = 3600, VaryByParam = "type;page;stl;ind;col")]
        public ActionResult List(string type, int? page, int? stl, int? ind, int? col)
        {
            var referenceTypes = (List<ProductPrice>)productService.GetReferenceProductPrice();
            var model = new List<ProductListItemViewModel>();
            foreach (var t in referenceTypes)
            {
                var product = productService.GetProductByFormfactorId(t.FormFactor.FormFactorId);
                model.Add(new ProductListItemViewModel
                {
                    Name = this.GetLocalizedName(product),
                    ImgPath = FileStoreHelper.GetProductTypeImgPath(product.ProductTypeId),
                    ReferencePrice = (t.Price4x0 != 0 ? t.Price4x0 : t.Price4x4) * t.Quantity,
                    ReferenceQuantity = t.Quantity,
                    ProductTypeId = product.ProductTypeId

                });
            }
            

            
           /* page = page.HasValue ? page : page = 1;
            ProductFilter filter = new ProductFilter()
            {
                StyleId = stl,
                IndustryId = ind,
                ColorId = col,
                ProductType = type,
                SkipItems = (page.Value - 1)*ITEMS_COUNT,
                TakeItems = ITEMS_COUNT
            };

            List<ProductViewModel> modelList = new List<ProductViewModel>();
            foreach (ProductDO prod in productService.GetFilteredProducts(filter))
            {
                modelList.Add(new ProductViewModel() 
                { 
                    ProductId = prod.Id,
                    Name = GetLocalizedName(prod),
                    TypeKey = prod.TypeKey,
                    ThumbnailPath = FileStoreHelper.GetProdThumbnailPath(prod.Id, prod.TypeKey)
                });
            }
            ViewData["products"] = modelList;

            int itemCount = productService.GetFilteredProductsCount(filter);
            int pageCount = itemCount / ITEMS_COUNT;
            if ((itemCount % ITEMS_COUNT) != 0)
            {
                pageCount++;
            }
            var pagingModel = new PagingViewModel()
            {
                CurrentPage = page.Value,
                TotalPages = pageCount
            };

            ViewData["pages"] = pagingModel;*/

            return View(model);
        }

        

        [HttpGet]
        [OutputCache(Duration=3600, VaryByParam="id")]
        public ActionResult Customize(long id)
        {/*
            ProductDO prod = productService.GetProductById(id);
            ProductViewModel viewModel = new ProductViewModel() 
            { 
                ProductId = prod.Id,
                Name = GetLocalizedName(prod),
                TypeKey = prod.TypeKey,
                DefaultDataTemplateId = prod.DefaultDataTemplate.Id,
                DesignPath = FileStoreHelper.GetProdDesignPath(prod.Id, prod.TypeKey)
            };
            
            
            ViewData["wizard"] = new ProductWizardViewModel()
            {
                DesignStepStatus = WizardStepStatus.Active,
                ConfigStepStatus = WizardStepStatus.Inactive,
                OrderStepStatus = WizardStepStatus.Inactive
            };

            return View(viewModel);*/
            return View();
        }

        [HttpPost]
        public ActionResult Customize(long id, FormCollection form)
        {/*
            //Optionally add text items string length validation
            int templId = Convert.ToInt32(form["templateId"]);

            InfoTemplate templateObj = productService.GetTemplateById(templId).Template;

            List<TextItem> customData = new List<TextItem>();
            foreach (TextItem item in templateObj.Items)
            {   
                if (!String.IsNullOrEmpty(form[item.FieldName]))
                {
                    item.Text = form[item.FieldName];

                    HttpContext.Profile.SetPropertyValue("FullName", form["fullName"]);
                    customData.Add(item);
                }
            }

            templateObj = new InfoTemplate()
            {
                Items = customData.ToArray(),
                Height = templateObj.Height,
                Width = templateObj.Width
            };
            PrintMediaDO defaultPrintMedia = productService.GetDefaultPrintMediaByProductId(id);
            PackageViewModel newPackage = new PackageViewModel() 
                                {
                                    InfoData = templateObj, 
                                    ProductId = id, 
                                    BaseTemplateId = templId,
                                    Date = DateTime.Now,
                                    PrintMediaCode = defaultPrintMedia.Code,
                                    PrintMethodCode = defaultPrintMedia.DefaultPrintMethod.Code,
                                    Quantity = 100,
                                    FinishingServiceTypes = new List<string>()
                                };
            ShoppingCart.Packages.Add(newPackage);
            ShoppingCart.CurrentPackage = newPackage;

            return RedirectToAction("ConfigPackage");
          * */
            return View();
        }

        [HttpGet]
        public ActionResult ConfigPackage()
        {
            /*
            if (ShoppingCart.CurrentPackage != null)
            {
                
                String productType = productService.GetProductById(ShoppingCart.CurrentPackage.ProductId).TypeKey ;

                TempData["price"] = billingService.GetProductPrice(ShoppingCart.CurrentPackage.ProductId,
                                                            ShoppingCart.CurrentPackage.PrintMediaCode,
                                                            ShoppingCart.CurrentPackage.PrintMethodCode,
                                                            ShoppingCart.CurrentPackage.Quantity,
                                                            DateTime.Now,
                                                            ShoppingCart.CurrentPackage.FinishingServiceTypes.ToArray());
                
                ViewData["wizard"] = new ProductWizardViewModel()
                {
                    DesignStepStatus = WizardStepStatus.Passed,
                    ConfigStepStatus = WizardStepStatus.Active,
                    OrderStepStatus = WizardStepStatus.Inactive
                };

                return View(ShoppingCart.CurrentPackage);
            }
            return RedirectToAction("List");
             * */
            return View();
        }

        [HttpPost]
        public ActionResult ConfigPackage(PackageViewModel packData)
        {
            /*
            if (ShoppingCart.CurrentPackage == null)
            {
                return RedirectToAction("List");
            }
            PackageViewModel pack = ShoppingCart.CurrentPackage;

            pack.PrintMediaCode = packData.PrintMediaCode;
            pack.PrintMethodCode = packData.PrintMethodCode;
            pack.Quantity = packData.Quantity;
            pack.FinishingServiceTypes = (new string[] { "LMMT" }).ToList(); //form.GetValues("finishings").ToList();


            pack.UserId = this.CurrentUserId;

            List<FinishingServiceDO> finishings ;
            if(pack.FinishingServiceTypes != null)
            {
                finishings = new List<FinishingServiceDO>(pack.FinishingServiceTypes.Count);
                foreach(var finishingCode in pack.FinishingServiceTypes){
                    finishings.Add(new FinishingServiceDO()
                    {
                        Code = finishingCode
                    });
                }
            }else{
                finishings = new List<FinishingServiceDO>();
            }
            PackageDO packageDo =  new PackageDO(){
                BackFace = new BackFaceDO() { Id = pack.BackFaceId},
                UserId = pack.UserId,
                DataTemplateBase = new DataTemplateDO(){Id = pack.BaseTemplateId},
                Date = pack.Date,
                InfoData = pack.InfoData,
                PrintMedia = new PrintMediaDO() {Code = pack.PrintMediaCode},
                PrintMethod = new PrintMethodDO(){Code = pack.PrintMethodCode},
                Product = new ProductDO() {Id = pack.ProductId},
                Quantity = pack.Quantity,
                TotalPrice = pack.TotalPrice,
                FinishingServices = finishings
            };



            long? packageId = productService.CreatePackage(packageDo);
            if (packageId.HasValue)
            {
                //Add notification
                return RedirectToAction("Order");
            }
            else
            {
                //Add error notification
                return RedirectToAction("ConfigPackage");
            }
             * */
            return View();

        }


        [HttpGet]
        public ActionResult Order()
        {
            ViewData["wizard"] = new ProductWizardViewModel()
            {
                DesignStepStatus = WizardStepStatus.Passed,
                ConfigStepStatus = WizardStepStatus.Passed,
                OrderStepStatus = WizardStepStatus.Active
            };
            return View("Order");
        }
        /// <summary>
        /// Returns image stream of newly created product
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult GetReviewImage()
        {
            /*
            if (ShoppingCart.CurrentPackage != null)
            {
                ProductDO product = productService.GetProductById(ShoppingCart.CurrentPackage.ProductId);
                string imagePath = Server.MapPath(FileStoreHelper.GetProdDesignPath(ShoppingCart.CurrentPackage.ProductId, product.TypeKey));
                MemoryStream image = (new TextImageGenerator()).GetReviewImageThumb(ShoppingCart.CurrentPackage.InfoData, ShoppingCart.CurrentPackage.ProductId, imagePath);
                return new FileContentResult(image.ToArray(), "image/png");
            }
            return RedirectToAction("List");
             * */
            return View();
        }

        [HttpGet]
        public ActionResult GetPrintMediaList(long id)
        {
            /*
            if (ShoppingCart.CurrentPackage != null)
            {
                string currentMediaCode = ShoppingCart.CurrentPackage.PrintMediaCode;
                List<PaperViewModel> paperViewModels = new List<PaperViewModel>();
                foreach (var printMedia in productService.GetMediaListByProductId(id))
                {
                    paperViewModels.Add(new PaperViewModel()
                    {
                        Code = printMedia.Code,
                        Description = GetLocalizedDescription(printMedia),
                        ImgPath = FileStoreHelper.GetPaperThumbnailPath(printMedia.Code),
                        Name = GetLocalizedName(printMedia),
                        BrandName = printMedia.Name,
                        Selected = currentMediaCode.Equals(printMedia.Code),
                        Type = printMedia.Type.Code
                    });
                }
                return View(paperViewModels);
            }* */
            return new EmptyResult();
             
        }

        [HttpGet]
        public ActionResult GetPrintMethodList(string id)
        {
            /*
            if (ShoppingCart.CurrentPackage != null)
            {
                //var defaultPrintMethod = productService.GetDefaultPrintMethodByMediaCode(id);
                List<PrintMethodViewModel> printMethods = new List<PrintMethodViewModel>();
                foreach (var printMethod in staticDataService.GetMediaPrintMethods(id))
                {
                    printMethods.Add(new PrintMethodViewModel()
                    {
                        Code = printMethod.Code,
                        Description = GetLocalizedDescription(printMethod),
                        ImgPath = FileStoreHelper.GetPrintingMethodThumbnailPath(printMethod.Code),
                        Name = GetLocalizedName(printMethod),
                        //Selected = defaultPrintMethod.Code.Equals(printMethod.Code)
                     
                    });
                }

                return View(printMethods);
            }
             * */
            return new EmptyResult();
        }

        [HttpGet]
        public ActionResult CalculatePriceJSON(int quantity, string mediaCode, string methodCode)
        {
            /*
            if (ShoppingCart.CurrentPackage != null)
            {
                var priceObj = new
                {
                    Price = billingService.GetProductPrice(ShoppingCart.CurrentPackage.ProductId,
                                               mediaCode, methodCode, quantity, DateTime.Now,
                                               ShoppingCart.CurrentPackage.FinishingServiceTypes.ToArray())
                };
                return Json(priceObj, JsonRequestBehavior.AllowGet);
            }
             * * */
            return new EmptyResult();
             
        }

        public ActionResult CalculatePrice(PriceCalculationViewModel model)
        {
            var price = productService.CalculatePrice(model.ProductType, model.Quantity, model.ColorMode, model.PrintMediaCode, model.FormFactorId);
            return Content(price.ToString("N0",CultureInfo.InvariantCulture) +" dr.");
        }

        
        [OutputCache(VaryByParam="none",Duration = Int32.MaxValue)]
        public ActionResult PriceCalculatorJSON()
        {
            return Json(GetCalculatorDropDownData((List<ProductType>)productService.GetAllProductTypesWithMediaAndFFactors()), JsonRequestBehavior.AllowGet);
        }

        public ActionResult PriceCalculatorNavControl()
        {
            var model = new PriceCalculationViewModel
            {
                ProductTypes = new List<SelectListItem>(),
                PrintMedias = new List<SelectListItem>(),
                ColorModes = new List<SelectListItem>()
            };
            
            var productTypes = (List<ProductType>)productService.GetAllProductTypes();
            model.ProductTypes = new List<SelectListItem>();
            productTypes.ForEach(m => model.ProductTypes.Add(new SelectListItem() { Text = GetLocalizedName(m), Value = m.ProductTypeId }));
            
            /*
            var mediaTypes = (List<PrintMedia>)productService.GetAllPrintMedias();
            model.PrintMedias = new List<SelectListItem>();
            mediaTypes.ForEach(m => model.PrintMedias.Add(new SelectListItem() { Text = this.GetLocalizedName(m), Value = m.PrintMediaCode }));
            */


            var colorModes = Enum.GetNames(typeof(ColorMode));
            model.ColorModes = new List<SelectListItem> 
            { 
                new SelectListItem{Text = "4 + 0", Value= ColorMode.Mode4x0.ToString()},
                new SelectListItem{Text = "4 + 4", Value= ColorMode.Mode4x4.ToString()},
                new SelectListItem{Text = "1 + 0", Value= ColorMode.Mode1x0.ToString()},
                new SelectListItem{Text = "1 + 1", Value= ColorMode.Mode1x1.ToString()},
                new SelectListItem{Text = "4 + 1", Value= ColorMode.Mode4x1.ToString()},
            };
            return PartialView(model);
        }

        [OutputCache(Duration = int.MaxValue, VaryByParam="id")]
        public ActionResult InfoDataFieldsControl(int id)
        {
            /*
            InfoTemplate templObj = productService.GetTemplateById(id).Template;
            return PartialView(templObj.Items);
             * */
            return View();
        }


        [ChildActionOnly]
        [OutputCache(Duration = int.MaxValue, VaryByParam = "id")]
        public ActionResult InfoLayoutListControl(long id)
        {
            /*
            List<DataTemplateViewModel> viewModels = new List<DataTemplateViewModel>();
            string productType = productService.GetProductById(id).TypeKey;
            foreach (DataTemplateDO template in productService.GetTemplatesByProductId(id))
            {
                viewModels.Add(new DataTemplateViewModel() {
                    DataTemplateId = template.Id,
                    Name = GetLocalizedName(template),
                    ProductType = productType,
                    ThumbnailPath = FileStoreHelper.GetLayoutThumbnailPath(template.Id, productType)
                });
            }

            return PartialView(viewModels);
             * */
            return View();
        }


        /// <summary>
        /// Retrieve DataTemplate object in JSON format
        /// by deserializing Template XML
        /// </summary>
        /// <param name="id">DataTemplate id</param>
        /// <returns>JSON serialized object</returns>
        /// 
        [OutputCache(Duration = int.MaxValue, VaryByParam = "id")]
        public ActionResult TemplateJSON(int id)
        {
            /*
            InfoTemplate templObj =  productService.GetTemplateById(id).Template;
            foreach (TextItem item in templObj.Items)
            {
                item.Text = DataRes.TemplateStrings.ResourceManager.GetString("FieldDefValue_" + item.FieldName);
            }
           // var serializer = new XMLSerializer();
           // System.IO.File.WriteAllText("c:\\ggg.xml", serializer.SerializeObject(testData1()));
            return Json(templObj, JsonRequestBehavior.AllowGet);
             * */
            return View();
        }


        private DropDownProductType[] GetCalculatorDropDownData(List<ProductType> products)
        {

            var dropDownData = new DropDownProductType[products.Count];

            for (int i = 0; i < products.Count; i++)
            {
                dropDownData[i] = new DropDownProductType()
                {
                    Name = this.GetLocalizedName(products[i]),
                    Code = products[i].ProductTypeId,
                    Medias = GetPrintMedias(products[i].PrintMedias.ToList()),
                    Colors = GetColorModes(products[i]),
                    FormFactors = GetFormFactors(products[i].FormFactors.ToList())
                };
                
            }

            return dropDownData;
        }

        private DropDownColor[] GetColorModes(ProductType productType)
        {
            switch (productType.DoubleSideOption)
            {
                case -1:
                    return new DropDownColor[]
                    {
                        new DropDownColor{Code = ColorMode.Mode4x0, Name="4 + 0"},
                        new DropDownColor{Code = ColorMode.Mode1x0, Name="1 + 0"},
                    };
                case 0:
                    return new DropDownColor[]
                    {
                        new DropDownColor{Code = ColorMode.Mode4x0, Name="4 + 0"},
                        new DropDownColor{Code = ColorMode.Mode4x4, Name="4 + 4"},
                        new DropDownColor{Code = ColorMode.Mode1x0, Name="1 + 0"},
                        new DropDownColor{Code = ColorMode.Mode1x1, Name="1 + 1"},
                        new DropDownColor{Code = ColorMode.Mode4x1, Name="4 + 1"},
                        
                    };
                case 1:
                    return new DropDownColor[]
                    {
                        new DropDownColor{Code = ColorMode.Mode4x4, Name="4 + 4"},
                        new DropDownColor{Code = ColorMode.Mode1x1, Name="1 + 1"},
                        new DropDownColor{Code = ColorMode.Mode4x1, Name="4 + 1"},
                    };
            }
            return null;
        }

        private DropDownPrintMedia[] GetPrintMedias(List<PrintMedia> printMedias)
        {
            DropDownPrintMedia[] data = new DropDownPrintMedia[printMedias.Count];

            for (int i = 0; i < printMedias.Count; i++)
            {
                data[i] = new DropDownPrintMedia()
                {
                    Name = this.GetLocalizedName(printMedias[i]),
                    Code = printMedias[i].PrintMediaCode,
                };
            }
            return data;

        }

        private DropDownFormFactor[] GetFormFactors(List<FormFactor> formFactors)
        {
            DropDownFormFactor[] data = new DropDownFormFactor[formFactors.Count];

            for (int i = 0; i < formFactors.Count; i++)
            {
                var defMedia = productService.GetDefaultPrintMedia(formFactors[i].FormFactorId);
                data[i] = new DropDownFormFactor()
                {
                    Name = this.GetLocalizedName(formFactors[i]),
                    Id = formFactors[i].FormFactorId,
                    SizeInfo = String.Format("{0}mm x {1}mm",formFactors[i].Width,formFactors[i].Height),
                    DefaultPrintMedia = defMedia != null ?defMedia.PrintMediaCode:""
                };
            }
            return data;

        }

        private InfoTemplate testData1()
        {
            InfoTemplate templ = new InfoTemplate();
            templ.Height = 141.732f;
            templ.Width = 255.118f;
            List<TextItem> items = new List<TextItem>();
            

            items.Add(new TextItem()
            {
                FieldName = "companyName",
                Color = "FF3333EE",
                FontId = 1,
                Size = 20,
                Align = new TextAlign()
                {
                    Halign = HalignType.CENTER,
                    GrowTo = GrowToType.MIDDLE,
                    Y = 110
                },
                CMYK = new CMYKColor()
                {
                    C = 79,
                    M = 79,
                    Y = 0,
                    K = 7
                },
                MaxLength = 20
            });
            
            items.Add(new TextItem()
            {
                FieldName = "companyMessage",
                Color = "FF333333",
                FontId = 1,
                Size = 10,
                Align = new TextAlign()
                {
                    Halign = HalignType.CENTER,
                    GrowTo = GrowToType.MIDDLE,
                    Y = 90
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 30
            });


            items.Add(new TextItem()
            {
                FieldName = "fullName",
                Color = "FF333333",
                FontId = 1,
                Size = 12,
                Align = new TextAlign()
                {
                    Halign = HalignType.CENTER,
                    GrowTo = GrowToType.MIDDLE,
                    Y = 75
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 30
            });

            items.Add(new TextItem()
            {
                FieldName = "email",
                Color = "FF333333",
                FontId = 1,
                Size = 12,
                Align = new TextAlign()
                {
                    Halign = HalignType.CENTER,
                    GrowTo = GrowToType.MIDDLE,
                    Y = 60
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 25
            });

            items.Add(new TextItem()
            {
                FieldName = "addressLine1",
                Color = "FF333333",
                FontId = 1,
                Size = 10,
                Align = new TextAlign()
                {
                    Halign = HalignType.ABSOLUTE,
                    GrowTo = GrowToType.RIGHT,
                    Y = 30,
                    X = 10
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 30
            });


            items.Add(new TextItem()
            {
                FieldName = "addressLine2",
                Color = "FF333333",
                FontId = 1,
                Size = 10,
                Align = new TextAlign()
                {
                    Halign = HalignType.ABSOLUTE,
                    GrowTo = GrowToType.RIGHT,
                    Y = 15,
                    X = 10
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 20,
                Style = new TextStyle()
                {
                    Bold = true,
                }
            });


            items.Add(new TextItem()
            {
                FieldName = "phone",
                Color = "FF333333",
                FontId = 1,
                Size = 10,
                Align = new TextAlign()
                {
                    Halign = HalignType.ABSOLUTE,
                    GrowTo = GrowToType.LEFT,
                    Y = 30,
                    X = 245
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 15,
                Style = new TextStyle()
                {
                    Italic = true
                }
            });

            items.Add(new TextItem()
            {
                FieldName = "mobile",
                Color = "FF333333",
                FontId = 1,
                Size = 10,
                Align = new TextAlign()
                {
                    Halign = HalignType.ABSOLUTE,
                    GrowTo = GrowToType.LEFT,
                    Y = 15,
                    X = 245
                },
                CMYK = new CMYKColor()
                {
                    C = 0,
                    M = 0,
                    Y = 0,
                    K = 80
                },
                MaxLength = 15,
                Style = new TextStyle()
                {
                    Italic = true
                }

            });
            templ.Items = items.ToArray();
            return templ;
        }
    }
}
